package folderLogger;

import java.io.File;
import java.io.FileFilter;

import folderLogger.CoverImageMod.ImageReferenceType;
import folderLogger.fileFilters.ExtensionFilterFactory;
import folderLogger.outputFile.FileAttributes;
import folderLogger.outputFile.OutputConsoleWriter;
import folderLogger.outputFile.OutputFileFormat;
import folderLogger.outputFile.OutputFileWriter;
import folderLogger.outputFile.OutputWriter;

public class FolderPrinter {
 
	private String rootFolderPath;
	private String outputFolder;
	private OutputFileFormat fileType;
	private OutputWriter outputWriter;
	private FileFilter filter;
	private ImageReferenceType imgRefType;
	private CoverImageMod imageMod;
	
	private static final String RESOURCES = "Resources";
	
	private String lastError;
	
	private boolean isActive;
	
	public FolderPrinter() {
		isActive = true;
	}

	public String getLastError() {
		return lastError;
	}
	
	public void setActiveMode(boolean isActive) {
		this.isActive = isActive; 
	}
	
	public int Run(OperationSettings settings)
	{
		lastError = null;
		
		if(settings == null)
		{
			lastError = "Settings not properly configured";
			return -3428;
		}
		this.rootFolderPath = settings.getRootFolderPath();
		this.outputFolder = settings.getOutputFolder();
		this.fileType = settings.getOutputFileFormat();
		
		this.filter = ExtensionFilterFactory.getExtensionFilter(settings.getFilterSettings().getFilterType(), settings.getFilterSettings().getExtensions());
		this.imgRefType = settings.getCopyImages();
		
		if(this.filter == null)
		{
			lastError = String.format("Filter Type not supported: %s", settings.getFilterSettings().getFilterType());
			return -43;
		}
		if(outputFolder == null || outputFolder == "")
		{
			lastError = "Invalid output folder";
			return -64;
		}
		File rootFolder = new File(rootFolderPath);
		if(!rootFolder.exists())
		{
			lastError = String.format("Root folder doesn't exist: %s", rootFolderPath);
			return -1;
		}
		if(isActive)
		{
			outputWriter = new OutputFileWriter(outputFolder, fileType, RESOURCES);
		}
		else
		{
			outputWriter = new OutputConsoleWriter(fileType, RESOURCES);
		}
		if(outputWriter.InitializeOutputFormatter() != 0)
		{
			lastError = String.format("Format not supported: %s", fileType);
			outputWriter.close();
			return -12;
		}
		if(!outputWriter.PreProcess(outputFolder))
		{
			lastError = String.format("Pre-process failure with output folder: %s", outputFolder);
			outputWriter.close();
			return -2;
		}
		int outputFileStatus = outputWriter.InitializeIndexFile();
		if(outputFileStatus < 0)
		{
			switch(outputFileStatus)
			{
			case -1:
				//	File exists
				lastError = String.format("Index file already exists in: %s", outputFolder);
				break;
			case -2:
				//	unable to create file; invalid path
				lastError = String.format("Unable to create index file. Invalid path: %s", outputFolder);
				break;
			default:
				lastError = String.format("Can't initialize index file in: %s", outputFolder);
				//	unknown error
				break;
			}
			
			outputWriter.close();
			return outputFileStatus;
		}
		//	Output file initialised successfully.
		outputWriter.WriteHeader(rootFolderPath, settings);
		
		imageMod = new CoverImageMod(settings.getOutputFolder(), RESOURCES);
		imageMod.setActiveMode(isActive);
		
		if(PrintFolder(rootFolder) != 0)
		{
			lastError = String.format("Failed to scan folder!");
			outputWriter.close();
			return -14;
		}
		
		outputWriter.WriteFooter();
		outputWriter.close();
		return 0;
	}

	private int PrintFolder(File currentFolder) {
		
		if(currentFolder == null)
		{
			return -1;
		}
		//	Item is a file
		if(!currentFolder.isDirectory())
		{
			FileAttributes attributes = new FileAttributes(false, "", 0, currentFolder.length());
			outputWriter.WriteFileHeader(currentFolder.getName(), attributes);
			outputWriter.WriteFileFooter(currentFolder.getName(), attributes);
			return 0;
		}
		//	Item is a directory
		String imageFileName = CoverImageMod.FindImageFile(currentFolder);
		imageFileName = imageMod.RenameImage(imageFileName, imgRefType);
		FileAttributes folderAttrib = new FileAttributes(true, imageFileName, currentFolder.listFiles().length, -1);
		outputWriter.WriteFolderHeader(currentFolder.getName(), folderAttrib);
		
		//	Print only folders
		for(File currentFile : currentFolder.listFiles())
		{
			if(currentFile.isDirectory())
			{
				PrintFolder(currentFile);
			}
		}
		//	Print only files
		for(File currentFile : currentFolder.listFiles(filter))
		{
			//	No filtering is done when filter == null
			if(!currentFile.isDirectory())
			{
				PrintFolder(currentFile);
			}
		}
		
		outputWriter.WriteFolderFooter(currentFolder.getName(), folderAttrib);
		
		return 0;
	}

}
